Skip to content

Conversation

@mjcross
Copy link
Contributor

@mjcross mjcross commented Oct 26, 2025

A proposed new NTP example that differs from the existing pico_w/wifi/ntp_client in the following ways:

  1. uses the SNTP app already provided by lwIP (in threadsafe background mode)
  2. uses pico_aon_timer to create a time-of-day clock that can be read asynchronously from user code
  3. illustrates the use of a POSIX timezone (TZ) to convert UTC to local time with daylight saving
  4. includes a README.md to explain what the example does and how to use it

The program connects to Wi-Fi, initialises the lwIP SNTP app, syncs the pico_aon_timer to NTP and then enters a loop to display the local time in London (or UTC, or whichever timezone the user defines); resynchronising to ntp.pool.org in the background every hour.

I suggest it's quite an important use case for the Pico-W, and illustrates a couple of features users may find helpful (such as how to create and use a POSIX timezone).

@lurch
Copy link
Contributor

lurch commented Oct 27, 2025

Hmmm, if #716 and #714 got together and had a baby... 🤔 😂

@mjcross
Copy link
Contributor Author

mjcross commented Oct 27, 2025

Hmmm, if #716 and #714 got together and had a baby... 🤔 😂

https://digitalcollections.smu.edu/digital/collection/tir/id/205/

@lurch
Copy link
Contributor

lurch commented Oct 28, 2025

Thanks for the extra comments 👍
Not having done any time-based processing in C myself, I was misreading asctime() as ascii_time() whereas I guess it's actually meant to be read as as_ctime() 😂

@mjcross
Copy link
Contributor Author

mjcross commented Oct 28, 2025

I was misreading asctime() as ascii_time() whereas I guess it's actually meant to be read as as_ctime() 😂

Oooo never considered that... My "lengthy and extensive research" (ha ha) suggests it might be the former: https://retrocomputing.stackexchange.com/questions/25601/what-is-the-meaning-of-asctime
In fact for anything more complex than a timestamp it's probably better to use strftime() but that's a bit OTT for an embedded app :-)

@mjcross
Copy link
Contributor Author

mjcross commented Oct 28, 2025

Found a way to avoid hardcoding the timezone names in the printf() :-)

@mjcross
Copy link
Contributor Author

mjcross commented Oct 28, 2025

Many thanks for the excellent suggestions - should be all wrapped up in the latest commit (please let me know if I missed anything)

@mjcross
Copy link
Contributor Author

mjcross commented Oct 28, 2025

Looking really good now - many thanks again for your time to review

setenv() requires <stdlib.h> which is included via lwIP. Make it explicit in case someone uses the timezone code in a different context.
@mjcross
Copy link
Contributor Author

mjcross commented Oct 30, 2025

Spent far too long today chasing down why some simple test code couldn't find the function definition for setenv(). Eventually realised it was because in the example I'd forgotten to #include <stdlib.h>, and got away with it because lwIP pulls it in.
Hopefully by importing it explicitly it'll save someone else from the same fate...

@mjcross
Copy link
Contributor Author

mjcross commented Jan 9, 2026

I discovered this was giving very incorrect times of day when run on RP2040. This is because the aon_timer on that platform has a resolution of only one second, which is incompatible with SNTP round-trip compensation. To fix this I have added a test in the example's CMakeLists.txt to disable SNTP_COMP_ROUNDTRIP in lwipopts.h for RP2040.
If you know of a cleaner/better way of handling it I'd be happy to oblige :-)

@lurch
Copy link
Contributor

lurch commented Jan 10, 2026

Looking at the RP2040 datasheet it seems like you could set up the RTC peripheral to trigger an interrupt once a minute (e.g. when the "seconds" value rolls around to 0), and then you could use the callback for that interrupt to read the current Timer peripheral value ("The system timer peripheral on RP2040 provides a global microsecond timebase for the system"). And then when you need the time with a smaller granularity than a second, you could re-read the timer again, subtract the value you stored in the callback, and that would give you the number of microseconds since the start of the last minute? (I guess it's very unlikely that an SNTP round-trip would take longer than a minute!)

Of course it's entirely up to you to decide if it's worth adding that level of complexity to your example 😉

@mjcross
Copy link
Contributor Author

mjcross commented Jan 10, 2026

Looking at the RP2040 datasheet it seems like you could set up the RTC peripheral to trigger an interrupt once a minute
[...]

very inventive!

Of course it's entirely up to you to decide if it's worth adding that level of complexity to your example 😉

To be honest if anyone needs round-trip compensation that much it'd be more cost-effective to just send them a free Pico2_W!

@mjcross
Copy link
Contributor Author

mjcross commented Jan 10, 2026

@lurch I was thinking more of the proposed method of adjusting the lwIP options depending on the platform (i.e. the condition in the CMakeLists.txt): I was wondering whether there was a more preferred way of doing that :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants